package cn.buk.tms.eotms.controller;

import cn.buk.tms.eotms.entity.PaymentOrder;
import cn.buk.tms.eotms.service.PaymentService;
import cn.buk.tms.exception.BaseException;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 *
 * @author yfdai
 * @date 2017-01-07
 */
@RestController
@RequestMapping("/alipay")
public class AlipayController extends BaseController {

  private static final Log logger = LogFactory.getLog(AlipayController.class);

  private static final String TRADE_CLOSED = "TRADE_CLOSED";
  private static final String TRADE_SUCCESS = "TRADE_SUCCESS";
  private static final String TRADE_FINISHED = "TRADE_FINISHED";

  @Autowired
  public AlipayController(PaymentService paymentService) {
    this.paymentService = paymentService;
  }

  // 应用ID
  @Value("${alipay_appid}")
  private String appId;

  // 商户私钥
  @Value("${alipay_private_key}")
  private String privateKey;

  // 支付宝公钥
  @Value("${alipay_public_key}")
  private String publicKey;

  // 服务器异步通知页面路径  需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
  @Value("${alipay_notify_url}")
  private String notifyUrl;

  // 页面跳转同步通知页面路径 需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
  @Value("${alipay_return_url}")
  private String returnUrl;



  // 签名方式
  private final String signType = "RSA2";

  // 字符编码格式
  private final String charset = "UTF-8";

  // 支付宝网关
  private final String gatewayUrl = "https://openapi.alipay.com/gateway.do";


  private PaymentService paymentService;


  @RequestMapping("/returnUrl")
  public String returnUrl(HttpServletRequest request) throws BaseException {
    logger.info("returnURL");

//    获取支付宝GET过来反馈信息
    Map<String, String> params = new HashMap<>(10);
    Map<String, String[]> requestParams = request.getParameterMap();
    for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
      String name = iter.next();
      String[] values = requestParams.get(name);
      String valueStr = "";
      for (int i = 0; i < values.length; i++) {
        valueStr = (i == values.length - 1) ? valueStr + values[i]
            : valueStr + values[i] + ",";
      }
      //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
      valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
      params.put(name, valueStr);
      logger.info("return_url " + name + ":" + valueStr);
    }


    //计算得出通知验证结果
    boolean verifyResult = false;
    try {
      verifyResult = AlipaySignature.rsaCheckV1(params, this.publicKey, this.charset, this.signType);
    } catch (AlipayApiException e) {
      e.printStackTrace();
    }

    if (!verifyResult) {
      logger.warn("To verify the message from alipay failed.");
//      return null;
    }

    verifyResult = true;

    //商户订单号
    String outTradeNo = params.get("out_trade_no");

    //支付宝交易号
    String tradeNo = params.get("trade_no");

    //交易状态
    String tradeStatus = params.get("trade_status");

    //买家支付宝账号
    String buyerEmail = params.get("buyer_email");

    //买家支付宝ID
    String buyerId = params.get("buyer_id");

    final double totalAmount = Double.parseDouble(params.get("total_amount"));

    if (verifyResult && tradeStatus != null) {//验证成功
      logger.info("returnURL: " + tradeStatus);

      if (TRADE_FINISHED.equals(tradeStatus) || TRADE_SUCCESS.equals(tradeStatus)) {
        PaymentOrder result = paymentService
            .updatePaymentOrderDone(outTradeNo, totalAmount, tradeNo, buyerId);
        if (result != null && result.getStatus() == PaymentOrder.PAYMENT_ORDER_SUCCESS) {
          return "success";
        } else {
          return "success, but order process failed.";
        }
      } else {
        return "trade status is ignored!";
      }
//      return "undo";
    } else {
      return "verified failed.";
    }
  }

  @RequestMapping("/notifyUrl")
  public String notifyUrl(HttpServletRequest request) throws BaseException {
    logger.info("notifyUrl");

//    JsonResult jsonResult = new JsonResult();
    //获取支付宝POST过来反馈信息
    Map<String, String> params = new HashMap<>(10);
    Map<String, String[]> requestParams = request.getParameterMap();
    for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
      String name = iter.next();
      String[] values = requestParams.get(name);
      String valueStr = "";
      for (int i = 0; i < values.length; i++) {
        valueStr = (i == values.length - 1) ? valueStr + values[i]
            : valueStr + values[i] + ",";
      }
      //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//      valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
//      valueStr = new String(valueStr.getBytes(ISO_8859_1), UTF_8);
      params.put(name, valueStr);
      logger.info(name + ": " + valueStr);
    }

    String output = "fail";

    /**
     * 修改订单状态
     * /**
     * 订单状态
     * 0-待付款
     * 1-（担保模式）已付款，待发货
     * 2-（担保模式）已发货，待确认
     * 3-(即时到帐模式)已付款，待发货
     * 4-交易取消
     * 9-交易结束
     */
    boolean verifyResult = false;
    try {
      verifyResult = AlipaySignature.rsaCheckV1(params, this.publicKey, this.charset, this.signType);
    } catch (AlipayApiException e) {
//      e.printStackTrace();
//      logger.error(e.getMessage());
      logger.error(e.getErrCode() + ": " + e.getErrMsg());
    }

    if (!verifyResult) {
      //TODO 改进这个问题
      logger.error("To verify the message from alipay failed.");
//      return null;
    }

    verifyResult = true;

    //商户订单号
    String outTradeNo = params.get("out_trade_no");
    //支付宝交易号
    String tradeNo = params.get("trade_no");
    //交易状态
    String tradeStatus = params.get("trade_status");
    //买家支付宝ID
    String buyerId = params.get("buyer_id");

    final double totalAmount = Double.parseDouble(params.get("total_amount"));

    if (verifyResult && tradeStatus != null) {//验证成功
      //自己的业务代码
      logger.info("notifyURL: " + tradeStatus + ", " + outTradeNo + ".");
      if (TRADE_FINISHED.equals(tradeStatus) || TRADE_SUCCESS.equals(tradeStatus)) {
        //该判断表示买家已经确认收货，这笔交易完成
        PaymentOrder result = paymentService.updatePaymentOrderDone(outTradeNo, totalAmount, tradeNo, buyerId);
        if (result != null && result.getStatus() == PaymentOrder.PAYMENT_ORDER_SUCCESS) {
          output = "success";
        } else {
          logger.info("PaymentOrder result is null.");
        }
      } else if (TRADE_CLOSED.equals(tradeStatus)) {
        //该判断表示已取消这笔交易
      } else {
        output = "success";
      }
    }

    logger.info(output);
    return output;
  }

  @RequestMapping("/check")
  public String checkOrder(
                           @RequestParam("orderNo") String orderNo) throws AlipayApiException {
    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
            this.appId,
            this.privateKey,"json",
            this.charset,
            this.publicKey,
            this.signType);
    AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
    request.setBizContent("{" +
            "\"out_trade_no\":\"" + orderNo + "\"}");
    AlipayTradeQueryResponse response = alipayClient.execute(request);
    if(response.isSuccess()){
      System.out.println("调用成功");
    } else {
      System.out.println("调用失败");
    }

    return response.isSuccess() + "";
  }

}
